package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/radovskyb/watcher"
)

func main() {

	args := os.Args
	//fmt.Println(args, "9999999999999999999999999", len(args))
	length := len(args)
	if length > 1 {
		if args[1] == "init" {
			if length == 2 {
				fmt.Println("Please input project name , example: eye init project_name")
				return
			}
			if length == 3 {
				initText := `
{
	"appName":"` + args[2] + `",
	"ignoreDir":["temp","test"],
	"runCmd":"",
	"buildCmd":"go build -o ",
	"buildDir":"",
	"lang":"go"
}
				`
				file_put_content(`eye.config`, initText)
				//ioutil.WriteFile(`eye.config`, []byte(initText), 0766)
				return
			}
			if length == 4 {
				if args[3] == "go" {
					initText := `
{
	"appName":"` + args[2] + `",
	"ignoreDir":["temp","test"],
	"runCmd":"",
	"buildCmd":"go build -o ",
	"buildDir":"",
	"lang":"go"
}
					`
					file_put_content(`eye.config`, initText)
					//ioutil.WriteFile(`eye.config`, []byte(initText), 0766)
					return
				}
				if args[3] == "rust" {
					initText := `
{
	"appName":"` + args[2] + `",
	"ignoreDir":["temp","test"],
	"runCmd":"",
	"buildCmd":"cargo run ",
	"buildDir":"",
	"lang":"rust"
}
					`
					file_put_content(`eye.config`, initText)
					//ioutil.WriteFile(`eye.config`, []byte(initText), 0766)
					return
				}
			}
		} else {
			fmt.Println("Eye got a params error", "you can use it like 'eye init project_name programming_language'", "example: eye init life rust")
			return
		}
	}

	dirName, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}
	configs := LoadConfig("./eye.config")
	fmt.Println("--- "+time.Now().Format("2006-01-02 15:04:05")+" eye start, dir: "+dirName+", configs:", configs)
	w := watcher.New()
	w.SetMaxEvents(1)
	ignoreDir := configs["ignoreDir"].([]interface{})
	w.Ignore(dirName + "/" + configs["appName"].(string))
	w.Ignore(dirName + "/.git")
	w.Ignore("./eye.config")
	lang := configs["lang"].(string)
	buildDir := configs["buildDir"].(string)
	if !strings.HasSuffix(buildDir, "/") {
		buildDir = buildDir + "/"
	}

	script := `#!/usr/bin/sh
` + dirName + "/" + buildDir + configs["appName"].(string) + " " + configs["runCmd"].(string)
	if lang == "rust" {
		script = `
cargo run
	`
	}
	os.Remove(configs["appName"].(string) + `_eye.sh`)
	file_put_content(configs["appName"].(string)+`_eye.sh`, script)
	// 保存到文件
	//ioutil.WriteFile(configs["appName"].(string)+`_eye.sh`, []byte(script), 0766)
	w.Ignore(dirName + "/" + configs["appName"].(string) + "_eye.sh")
	for _, v := range ignoreDir {
		w.Ignore(dirName + "/" + v.(string))
	}
	go func(dirName, appName, runCmd, buildCmd, buildDir, lang string) {
		for {
			select {
			case event := <-w.Event:
				if !event.FileInfo.IsDir() {
					fmt.Println("--- "+time.Now().Format("2006-01-02 15:04:05"), event)
					go Handle(dirName, appName, runCmd, buildCmd, buildDir, lang)
				}
			case err := <-w.Error:
				log.Fatalln(err)
			case <-w.Closed:
				return
			}
		}
	}(dirName, configs["appName"].(string), configs["runCmd"].(string), configs["buildCmd"].(string), buildDir, configs["lang"].(string))

	// Watch test_folder recursively for changes.
	if err := w.AddRecursive(dirName); err != nil {
		log.Fatalln(err)
	}

	// Trigger 2 events after watcher started.
	go func() {
		w.Wait()
		w.TriggerEvent(watcher.Create, nil)
		//w.TriggerEvent(watcher.Remove, nil)
	}()

	// Start the watching process - it'll check for changes every 100ms.
	if err := w.Start(time.Millisecond * 100); err != nil {
		log.Fatalln(err)
	}
}
